package cn.xshi.gateway.config;

import cn.xshi.gateway.route.service.DynamicRouteEvent;
import cn.xshi.sentinel.log.MetricLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
 * @Desc Bean Config
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
@Configuration
public class BeanConfig {

    /**
     * 开启Sentinel客户端日志上报
     * @return
     */
    @Bean(destroyMethod = "destroy", initMethod = "execute")
    public MetricLog initUploadLogBean(){
        return new MetricLog();
    }

    /**
     * 监听路由
     * @return
     */
    @Bean(destroyMethod = "destroy", initMethod = "execute")
    public DynamicRouteEvent initRouteBean(){
        return new DynamicRouteEvent();
    }


    /**
     *
     * @return
     */
    @Bean(name = "gatewayThreadPool")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(5);//业务实时推送（核心线程数，线程池中始终存活的线程数 默认5）
        pool.setMaxPoolSize(10); //业务实时推送（最大线程数，线程池中允许的最大线程数，当线程池的任务队列满了之后可以创建的最大线程数。默认10）
        pool.setQueueCapacity(100);//队列容量,当核心线程数达到最大时，新任务会放在队列中排队等待执行（业务实时推送（使用有界队列允许存放100个任务，避免OOM 默认100））
        pool.setKeepAliveSeconds(300);//线程空闲时间（业务实时推送（最大线程数可以存活的时间，当线程中没有任务执行时，最大线程就会销毁一部分，最终保持核心线程数量的线程。默认300s））
        pool.setAllowCoreThreadTimeOut(false);//线程空闲时间,当线程空闲时间达到keepAliveSeconds(秒)时,线程会退出,直到线程数量等于corePoolSize,如果allowCoreThreadTimeout=true,则会直到线程数量等于0
        pool.setRejectedExecutionHandler(new RejectedExecutionHandler() {//自定义拒绝策略
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                log.warn("网关路由处理任务较慢 ,线程池丢弃该任务！");//业务日志一个小时预计写入500*5MB
            }
        });
        //pool.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
        return pool;
    }
}